/*
    仪器发货申请
    从申批通过的合同中选择仪器

*/
public without sharing class InstrumentDeliveryController {
   
    public String msg {get;private set;}
    public Boolean isErr {get; private set;}//错误
    public Boolean isSuccess {get; private set;}//是否保存成功
    public class ControllerException extends Exception {}
    public String backId {get; private set;}
    public String type ;

    public String dataJson {get; private set;}
    public String saveJson {get; set;}
    public String searchJson {get; set; }
    private String sealflag ;
    public Boolean editRight {get;private set;}
    private User u ;

    private Boolean isNew ;
    public  Boolean isSale{get; private set;}
    public Boolean isLogistic {get; private set;}
    private String logiStage ;
    private InstrumentDeliveryApplication__c ida ;
    private Map<String,DataUtil.SObjectBean> stageObjectMap ; 

    private Map<String,Decimal> cpNumMap; //记录已经存在的明细的数量

    public InstrumentDeliveryController() {
        stageObjectMap = new  Map<String,DataUtil.SObjectBean>();
         backId = System.currentPageReference().getParameters().get('id');
         type = System.currentPageReference().getParameters().get('type');
         isSuccess = false;
          u = [select subCompany__c ,Profile.Name ,FinancialManager__c from User where Id =:UserInfo.getUserId()];

         editRight = u.Profile.Name.contains('助理')|| u.Profile.Name.contains('呼叫中心');//;
         isLogistic = u.Profile.Name.contains('物流')  ;
         logiStage = System.currentPageReference().getParameters().get('stage');
         isNew = false;
         cpNumMap = new Map<String,Decimal>();
        
         //isLogistic = true;


    }

    public void init(){

         try{
            setNil();
            if(backId == null )setErr('打开页面错误!');
            Opportunity opp =  new Opportunity();
            if(Id.valueOf(backId).getSObjectType() == InstrumentDeliveryApplication__c.SObjectType ){

                ida = [select Id,InvoicingCustomers__c,Opportunity__c,NC__c ,FinancialManager__c,RecordType.DeveloperName  ,OwnerId  ,DeliveryRelatedContracts__c  
                from InstrumentDeliveryApplication__c where Id =:backId];



                if(ida.Opportunity__c != null ) opp = [select Id ,AccountId ,Account.Name,Account.RecordType.DeveloperName from Opportunity where Id=:ida.Opportunity__c];


                if(!isLogistic &&  ida.NC__c == true) setErr('已同步NC不能修改!');

                isSale = ida.RecordType.DeveloperName  == 'SalesOutlet';

            }else if(Id.valueOf(backId).getSObjectType() == Opportunity.SObjectType){
                
                isNew = true;
                // con = [select Id ,Account__c,Account__r.RecordType.DeveloperName ,Account__r.Name from Contract__c where Id =: backId];
                 opp = [select Id ,AccountId ,Account.Name ,Account.RecordType.DeveloperName from Opportunity where Id=:backId];
                ida = new InstrumentDeliveryApplication__c();
               // ida.DeliveryRelatedContracts__c = backId;
                ida.Opportunity__c = backId;
                //ida.InvoicingCustomers__c = con.Account__c;
                ida.InvoicingCustomers__c = opp.AccountId;
                ida.OwnerId = UserInfo.getUserId();

                //if(con.Account__r.RecordType.DeveloperName == 'TerminalCustomer' )ida.ReceivingCustomer__c = con.Account__c ;
                ida.RecordTypeId = type != null && type == 's' ? Utils.getRecordTypeIdByDevNameAndObjName('SalesOutlet', 'InstrumentDeliveryApplication__c') : Utils.getRecordTypeIdByDevNameAndObjName('AbnormalSalesOutlet', 'InstrumentDeliveryApplication__c');
                isSale = type == 's';

                // ida.FinancialManager__c = u.FinancialManager__c;
                // if(u.FinancialManager__c == null )setErr('请联系管理员维护财务会计信息!');

            }else {
                setErr('打开页面错误!');
            } 

             u = [select SubsidiariesDistricts__c,SubCompany__c  from User where Id=:ida.OwnerId ]; 
            List<UserInformation__c> uaL = [select FinancialManager__c from UserInformation__c where Company__c =: u.SubsidiariesDistricts__c  ];
            if( !uaL.isEmpty() && uaL.get(0).FinancialManager__c != null )ida.FinancialManager__c = uaL.get(0).FinancialManager__c ;


            Map<String,Object> dataMap = new Map<String,Object>();
            if(isLogistic && !System.Test.isRunningTest()){
                dataMap.put('logistic', getLogicDetails());
            }else{
                dataMap.put('detail', getDetails());
                dataMap.put('search', getProductFromCoop());
                Map<String ,Map<String,String>> comboboxMap  = getCombox('ConfigurationListDetail__c',new Set<String>{'OrderMethod__c','IsStandard__c','CoopType__c'});
                comboboxMap.put('ISE__c', ImportObject.getPicklistValues('InstrumentDeliverynDetails__c', 'ISE__c', true));
                comboboxMap.put('LineType__c', ImportObject.getPicklistValues('InstrumentDeliverynDetails__c', 'LineType__c', true));
                dataMap.put('combobox',comboboxMap);
                dataMap.put('searchObject',getSearchObject());
                //dataMap.put('InstrumentDeliveryApplication__c',getSODField()); 

                 //字段
                 Map<String,Set<String>> fieldsmap = getFields();
                 //字段详情
                 Map<String, List<DataUtil.FieldBean>> fbMap = DataUtil.getFieldsBean(fieldsmap,stageObjectMap);
                
                //字段赋值
               

                 Map<String,List<DataUtil.FieldBean>> fields = DataUtil.setFieldsValue(fbMap, DataUtil.getBaseInfo(fbMap,stageObjectMap) );
                 if(isNew){

                     for (DataUtil.FieldBean fb   :  fields.get('InstrumentDeliveryApplication__c')) {
                        Map<String,Object> vMap  = new Map<String,Object>();
                        if(fb.name == 'ReceivingCustomer__c'){

                            vMap.put('Id', opp.AccountId );
                            vMap.put('Name', opp.Account.Name );
                            if(opp.Account.RecordType.DeveloperName != 'Dealer')fb.value = vMap;
                        }    
                    } 

                 }
                

                dataMap.put('base',fields);
                dataMap.put('baseObject',DataUtil.getBaseObjectMap(stageObjectMap));

            }

             


            dataJson = EncodingUtil.urlEncode(JSON.serialize(dataMap ),'UTF-8');

            sealflag  =  'Y-'+ ImportObject.getPicklistValues('Contract__c','Corpcode__c',false).get(u.subCompany__c);
        }catch(Exception e){
            isErr = true ; 
            ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR ,e.getMessage()));

        }

    }

     private Map<String ,Map<String,String>> getCombox(String objName ,Set<String> fields ){
        Map<String ,Map<String,String>> tmp = new Map<String ,Map<String,String>>();
        for(String f : fields){
            Map<String,String> pickMap = ImportObject.getPicklistValues(objName, f, true);
            tmp.put(f, pickMap);
        }
        return tmp;
    } 

   
    public List<LogisticProductBean> getLogicDetails(){
        List<LogisticProductBean> tmp = new List<LogisticProductBean>();
        for ( InstrumentDeliverynDetails__c idd :[select Id ,DeliveryInstrument__r.Product__r.Name ,TrackingNumber__c,ActualArrivalTme__c,
        ActualDepotTime__c,FuselageNumber__c ,Number__c,OutdoorNo__c 
            from InstrumentDeliverynDetails__c where ReturnToMainTable__c =: ida.Id  ] ) {
            
            tmp.add(new LogisticProductBean(idd));
        }

        return tmp;

    }

    //从合同中选择仪器
    public List<ProductBean> getProductFromCoop(){

        String basesql = 'select Id ,Product__c ,Product__r.MatchingInstrument__c,Product__r.ManualImportIdentification__c,Product__r.ProductName__c,Product__r.Spec__c,Product__r.NCCode__c,Product__r.Name,'+
        'Product__r.SerialNo__c,Product__r.Brand__c,ApplicationQuantity__c,DeliveryQuantity__c,SalesPrice__c,Product__r.Category0__c ,BloodSugarOrderDetail1__r.BloodSugarOrder__r.Name , EndCustomer__r.Name, '+
        ' QuoteProduct__r.Quote__r.Name ,Measure_Calculate_Product__r.Measure_Calculate__r.Name , InstrumentPolicy__r.InstrumentPolicy__r.Name,Product__r.InstrumentType__c,Product__r.NCinvshortname__c   '+
        'from ContractProduct__c where Opportunity__c =\''+ida.Opportunity__c+'\' ';

        if(type == 'b'){
            basesql += ' and Contract__r.Status__c !=\'已生效\' ';
        }else{
            //' and Contract__r.Status__c !=\'已生效\' ' +
            basesql +=  (isSale ? ' and CoopType__c  = \'正常销售\' ' : ' and CoopType__c  = \'投放\' ' );

        }


        List<ProductBean> tmp = new List<ProductBean>();

        Set<String > psets = new Set<String>();

        //1加载合同产品中的仪器
        String equip_sql = basesql + ' and  Product__r.Category0__c in ('+Label.DeliverySelectionRange+') ';//and DeliveryQuantity__c != null and   DeliveryQuantity__c > 0 
        //System.debug('InstrumentDeliveryController==> '+sql);
        List<ContractProduct__c> cpList = Database.query(equip_sql);
        //<产品Id,<配置清单>>
        Map<Id,List<ConfigBean>> cfgMap = new Map<Id,List<ConfigBean>>();
        
        for(ContractProduct__c cpequip : cpList ){

            //如果可发货数量 == 0 且 不在填写过的明细里 则不能选择
            if(cpequip.DeliveryQuantity__c == 0 &&  !cpNumMap.containsKey(cpequip.Id ))continue;


            psets.add(cpequip.Product__c );
            if(cfgMap.containsKey(cpequip.Product__c )) continue;
            List<ConfigBean> cfgL = cfgMap.containsKey(cpequip.Product__c) ? cfgMap.get(cpequip.Product__c) : new List<ConfigBean>();
            
            if(cpequip.Product__r.NCCode__c != null )cfgL.add(new ConfigBean(cpequip));
            
            cfgMap.put(cpequip.Product__c, cfgL);


        }
        System.debug('InstrumentDeliveryController==>'+ cfgMap);


        //2 加载合同产品中的 配套软件 和 设备
        String related_sql =  basesql + ' and  Product__r.MatchingInstrument__c in (\''+ String.join(new List<String>(psets), '\',\'')+'\') ';

        Set<String> expsets = new Set<String>();
        for(ContractProduct__c cpequip : Database.query(related_sql)){

            expsets.add(cpequip.Product__c );
            List<ConfigBean> cfgL = cfgMap.containsKey(cpequip.Product__r.MatchingInstrument__c) ? cfgMap.get(cpequip.Product__r.MatchingInstrument__c) : new List<ConfigBean>();
            cfgL.add(new ConfigBean(cpequip));
            System.debug('InstrumentDeliveryController==>'+ cpequip);
            cfgMap.put(cpequip.Product__r.MatchingInstrument__c, cfgL);


        }
        //3.加载配置清单的产品
        Set<String> pls= new Set<String>{'试剂','质控','校准','耗品','耗材'};
        for(ConfigurationListDetail__c cfg :
             [select Id ,Amount__c ,IsStandard__c ,OrderMethod__c ,InstrumentModel__c, Configuration__c , Configuration__r.Category0__c ,
             Configuration__r.Brand__c,Configuration__r.Spec__c,Configuration__r.SerialNo__c,Configuration__r.NCCode__c,Configuration__r.NCinvshortname__c,
             Configuration__r.ProductName__c ,Remark__c,Name
             from ConfigurationListDetail__c where InstrumentModel__c in: psets and InstrumentModel__c not in:expsets  
             and ProductLine__c not in:pls order by OrderMethod__c desc ]){

            List<ConfigBean> cfgL = cfgMap.containsKey(cfg.InstrumentModel__c) ? cfgMap.get(cfg.InstrumentModel__c) : new List<ConfigBean>();
            System.debug('InstrumentDeliveryController==>'+ cfg);

            cfgL.add(new ConfigBean(cfg));
            cfgMap.put(cfg.InstrumentModel__c, cfgL);

        }

        System.debug('InstrumentDeliveryController==>'+ cfgMap);

        //将配置清单 匹配到明细
        for(ContractProduct__c cpequip : cpList ){
            //如果可发货数量 == 0 且 不在填写过的明细里 则不能选择
            if(cpequip.DeliveryQuantity__c == 0 &&  !cpNumMap.containsKey(cpequip.Id ))continue;

            ProductBean p = new ProductBean(cpequip,cfgMap.get(cpequip.Product__c));
            if(cpNumMap.containsKey(p.cpId))p.cannum += cpNumMap.get(p.cpId);
            tmp.add(p);

        }
        return tmp;


        

    }

    public void saveLogistic(){
        msg = '';
        try {

            List<Object> saveList = ( List<Object> )JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson,'UTF-8'));
            System.debug(EncodingUtil.urlDecode(saveJson,'UTF-8'));
            List<InstrumentDeliverynDetails__c> indList =new List<InstrumentDeliverynDetails__c>();

            for (Object o  : saveList) {
                Map<String,Object> mo = (Map<String,Object>)o ;
                InstrumentDeliverynDetails__c idd = new InstrumentDeliverynDetails__c();
                idd.Id = DataUtil.getStringValue(mo.get('idId'));
                String delieverdate = DataUtil.getStringValue(mo.get('delieverdate'));
                idd.OutdoorNo__c = DataUtil.getStringValue(mo.get('outno'));
                idd.FuselageNumber__c = DataUtil.getStringValue(mo.get('eno'));

                idd.ActualDepotTime__c = String.isBlank(delieverdate) ? null :  Date.valueOf(delieverdate);
                String arrivaldate = DataUtil.getStringValue(mo.get('arrivaldate'));
                idd.ActualArrivalTme__c = String.isBlank(arrivaldate) ? null : Date.valueOf(arrivaldate);
                String expectdate = DataUtil.getStringValue(mo.get('expectdate'));

                idd.LogisticsExpectedArrivalTime__c = String.isBlank(expectdate) ? null :  Date.valueOf(expectdate);

                idd.TrackingNumber__c = DataUtil.getStringValue(mo.get('logicinfo'));
                indList.add(idd);

            }

            SavePoint sp  = Database.setSavepoint();
            try {
                
                if(indList.size() > 0 ) update indList;
                msg = '保存成功!';
                isSuccess = true;

            }catch (Exception e) {
                Database.rollback(sp);
                msg = '保存失败:'+e.getMessage();

            }
            
        }catch (Exception e) {
            msg = '保存失败:'+e.getMessage();
        }

    }
 
    public void save(){
        msg = '';
        try {

            Map<String,Object> saveMap = (Map<String,Object>)JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson,'UTF-8'));
            Map<String,Object> baseMap = (  Map<String,Object>)saveMap.get('base');

            Map<String,Set<String>> fieldsMap = getFields();
            Map<String,DataUtil.FieldBean> fbeanMap = DataUtil.getFieldsInfo(InstrumentDeliveryApplication__c.SObjecttype,fieldsMap.get('InstrumentDeliveryApplication__c'));
            for(String field : baseMap.keySet()){

                if(fbeanMap.containsKey(field))ida.put(field, DataUtil.dataHandler(baseMap.get(field),fbeanMap.get(field).type.toUpperCase() ));
            }

            List<Object> saveList = (List<Object>)saveMap.get('datas');
            List<InstrumentDeliverynDetails__c> indList =new List<InstrumentDeliverynDetails__c>();
            Set<Id> exsets = new Set<Id>();

            Set<Id> exsubSets = new Set<Id>();

            Map<String,List<NCOutsourcingProducts__c>> subsMap = new Map<String,List<NCOutsourcingProducts__c>>();
            for(Object o : saveList){
                Map<String,Object> mo = (Map<String,Object>)o;

                InstrumentDeliverynDetails__c idd = new InstrumentDeliverynDetails__c();

                Id iddid = mo.get('idId') == null ? null : Id.valueOf(DataUtil.getStringValue(mo.get('idId')));
                
                if(iddid != null ){
                    
                    idd.Id = iddid;
                    exsets.add(iddid);

                }
                if(iddid == null )idd.ReturnToMainTable__c = ida.Id ;
                idd.DeliveryInstrument__c = DataUtil.getStringValue(mo.get('cpId'));
                idd.Number__c =  DataUtil.getDecimalValue(mo.get('num'));
                idd.ISE__c = DataUtil.getStringValue(mo.get('isISE'));
                idd.LineType__c = DataUtil.getStringValue(mo.get('lineType'));
                indList.add(idd);

                List<Object> subs = (List<Object>)mo.get('subs');
                List<NCOutsourcingProducts__c> npl = new List<NCOutsourcingProducts__c>();

                if(subs == null || subs.isEmpty()) {
                    msg = '请维护仪器('+DataUtil.getStringValue(mo.get('productName'))+')配套产品信息!';
                    return;
                }
                for(Object subo : subs){
                    System.debug('InstrumentDeliveryController==> '+ subo );
                    Map<String,Object> smo = (Map<String,Object>)subo;
                    NCOutsourcingProducts__c np = new NCOutsourcingProducts__c();
                    Id rid  = smo.get('rid') == null ? null : Id.valueOf(DataUtil.getStringValue(smo.get('rid')));
                    if(rid != null){
                        np.Id = rid;
                        exsubSets.add(rid);
                    }

                    //if(iddid != null ) np.InstrumentDeliveryDetails__c = iddid;
                    System.debug('InstrumentDeliveryController==> '+ smo.get('productId')+'ddd' );
                    String productId =  DataUtil.getStringValue(smo.get('productId')) ;
                    np.NCProducts__c =String.isBlank(productId) ? null : productId;
                    np.Number__c = DataUtil.getDecimalValue(smo.get('num'));
                    np.Remarks__c = DataUtil.getStringValue(smo.get('remark'));
                    np.OrderMethod__c = DataUtil.getStringValue(smo.get('orderMethod'));
                    np.IsStandard__c = DataUtil.getStringValue(smo.get('isStandard'));
                    np.Configuration__c = DataUtil.getStringValue(smo.get('cfgId'));
                    np.Name = DataUtil.getStringValue(smo.get('name')); 
                    np.ContractProduct__c = DataUtil.getStringValue(smo.get('cpId'));
                    np.UnitPrice__c = DataUtil.getDecimalValue(smo.get('price'));
                    npl.add(np);
                    System.debug('InstrumentDeliveryController==> '+ npl);

                }
            
                subsMap.put(idd.DeliveryInstrument__c ,npl);

            }

            SavePoint sp = Database.setSavepoint();
            try {
                System.debug('InstrumentDeliveryController==>'+exsubSets);
                System.debug(exsets);
                if(!isNew){
                     delete [select Id from NCOutsourcingProducts__c where InstrumentDeliveryDetails__r.ReturnToMainTable__c =: backId and  Id not in : exsubSets];
                    delete [select Id from InstrumentDeliverynDetails__c where ReturnToMainTable__c =: backId and  Id not in : exsets];
                }
                upsert ida;

                
                for ( InstrumentDeliverynDetails__c idd : indList) {
                    if(idd.Id == null )idd.ReturnToMainTable__c = ida.Id;
                }

                
               
                if(indList.size() > 0 ) upsert indList;
                List<NCOutsourcingProducts__c> npList = new List<NCOutsourcingProducts__c>();
                for(InstrumentDeliverynDetails__c idd: indList){

                    for(NCOutsourcingProducts__c np: subsMap.get(idd.DeliveryInstrument__c )){
                        if(np.Id == null )np.InstrumentDeliveryDetails__c = idd.Id;
                        npList.add(np);
                    }
                }
                System.debug(JSON.serialize(npList));
                if(npList.size() > 0 ) upsert npList;
                backId = ida.Id;

                msg = '保存成功!';
                isSuccess = true;
            }catch (Exception e) {
                if(isNew) ida.Id = null;
                Database.rollback(sp);
                msg = '保存失败:'+e.getMessage()+e.getStackTraceString();



            }


        }catch (Exception e) {
            msg = '保存失败:'+e.getMessage()+e.getStackTraceString();
        }
        System.debug('InstrumentDeliveryController==>'+msg);
        

    }

      public void searchProduct(){

        Map<String,Object> searchMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(searchJson,'UTF-8'));
        //Category0__c not in (\'试剂\',\'仪器\',\'耗品\',\'质控\',\'第三方产品\',\'校准\',\'试纸\') or
        String sql = ' select Id  ,ProductName__c ,SerialNo__c , Brand__c ,Spec__c,Category0__c,NCCode__c ,Category1__c ,Model__c,SealCompany__c,NCinvshortname__c from Product__c where  Createddate != null and Company__c like \'%'+u.SubCompany__c+'%\' ';
        sql += ' and  (not SealCompany__c  like \'%'+sealflag+'%\')  and pk_invbasdoc__c != null  ';

        sql += ' and ( Category0__c not in (\'试剂\',\'仪器\',\'耗品\',\'质控\',\'校准\',\'耗材\') or ((Brand__c like \'%希森美康%\' Or Brand__c like \'%日立%\') and Category0__c = \'仪器\')) ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('ProductName__c'))) == false) sql += ' and ProductName__c like \'%'+DataUtil.getStringValue(searchMap.get('ProductName__c'))+'%\' ';

        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Brand__c'))) == false) sql += ' and Brand__c like \'%'+DataUtil.getStringValue(searchMap.get('Brand__c'))+'%\' ';

        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Spec__c'))) == false) sql += ' and Spec__c like \'%'+DataUtil.getStringValue(searchMap.get('Spec__c'))+'%\' ';

        if(String.isBlank(DataUtil.getStringValue(searchMap.get('SerialNo__c'))) == false) sql += ' and SerialNo__c like \'%'+DataUtil.getStringValue(searchMap.get('SerialNo__c'))+'%\' ';
 
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category0__c'))) == false) sql += ' and Category0__c like \'%'+DataUtil.getStringValue(searchMap.get('Category0__c'))+'%\' ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category1__c'))) == false) sql += ' and Category1__c like \'%'+DataUtil.getStringValue(searchMap.get('Category1__c'))+'%\' ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('NCCode__c'))) == false) sql += ' and NCCode__c like \'%'+DataUtil.getStringValue(searchMap.get('NCCode__c'))+'%\' ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Model__c'))) == false) sql += ' and Model__c like \'%'+DataUtil.getStringValue(searchMap.get('Model__c'))+'%\' ';

        sql += ' limit 200 ';
      
        System.debug('InstrumentDeliveryController==>'+sql);
          List<ConfigBean> tmp = new List<ConfigBean>();
          for(Product__c p : Database.query(sql)){
            ConfigBean  cb = new ConfigBean(p);
            cb.canChangenum = true;
            cb.canChangeorderMethod = true;
            cb.canChangeisStandard = true;
            tmp.add(cb);

          }
          dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp),'UTF-8');


    }
    public Map<String,Set<String>>  getFields(){
        Map<String,Set<String>> fieldsMap  = new  Map<String,Set<String>>();
        
            DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

            sb.title ='';
            sb.objname = 'InstrumentDeliveryApplication__c';
            sb.stype = DataUtil.getSObjectType('InstrumentDeliveryApplication__c');
            if(!isNew)sb.idvalue = ida.Id;
            sb.type = 'base';
            if(!isNew)sb.condition = ' where Id =\''+ida.Id+'\'';
            stageObjectMap.put('InstrumentDeliveryApplication__c',sb );
            Set<String>  fields = editRight ? new Set<String>{'DocumentTypes__c','PhysicalDelivery__c','GroupAllocation__c','AllocationCompany__c','DemandWarehouse__c','FollowupProcessing__c','InventoryStatus__c'}
            :new Set<String>{'ReceivingCustomer__c','FollowupProcessing__c','RequestArrivalDate__c','InventoryStatus__c',
                'Remark__c','LaboratoryFloor__c','ReceiverTelephone__c','ReceivingAddress__c','TimeReceipt__c','ReceivingDepartment__c',
                'Elevator__c','Reagents__c','TimeReceipt__c',
                'SiteAssistConsignee__c','DoorwaySize__c','IntoCityTime__c','UnloadingPoint__c','TransportChannel__c','SceneTakeDelivery__c','SmallSteps__c',
                'RequestReceive__c','ElevatorSize__c','ElevatorLoad__c','StaircaseWidth__c','MaximumCornerWidth__c','StepNo__c','LimitPeriod__c' };

            // if(isLogistic){

            //  fields = logiStage == 'send' ?  new Set<String>{'TrackingNumber__c','LogisticsExpectedArrivalTime__c','ActualDepotTime__c'} : new Set<String>{'ActualArrivalTme__c'};

            // } 
            //'FollowupProcessing__c','PhysicalDelivery__c','DocumentTypes__c',
            //: new Set<String>'TrackingNumber__c','LogisticsExpectedArrivalTime__c'

            /*Set<String>  fields =new Set<String>{'DocumentTypes__c','InventoryStatus__c','ReceivingCustomer__c','PhysicalDelivery__c','FollowupProcessing__c','InventoryStatus__c','RequestArrivalDate__c',
            'Remark__c','DocumentTypes__c','LaboratoryFloor__c','ReceiverTelephone__c','ReceivingAddress__c','TimeReceipt__c','ReceivingDepartment__c',
            'Elevator__c','Reagents__c','StaircaseWidth__c','TrackingNumber__c','LogisticsExpectedArrivalTime__c','SiteAssistConsignee__c','ElevatorSize__c','ElevatorLoad__c',
            'DoorwaySize__c','IntoCityTime__c','UnloadingPoint__c','TransportChannel__c','SceneTakeDelivery__c','LimitPeriod__c','SmallSteps__c','MaximumCornerWidth__c',
            'RequestReceive__c','StepNo__c'};*/

            if(isSale)fields.remove('FollowupProcessing__c');
            if(isSale)fields.remove('PhysicalDelivery__c');
            if(isSale)fields.remove('DocumentTypes__c');


            fieldsMap.put('InstrumentDeliveryApplication__c', fields);
        
        return fieldsMap;
    }

    private Map<String,List<DataUtil.FieldBean>> getSearchObject(){
        Map<String,List<DataUtil.FieldBean>> searchMap = new Map<String,List<DataUtil.FieldBean>>();

        Map<String,DataUtil.FieldBean>proMap = DataUtil.getFieldsInfo(Product__c.SObjecttype, new Set<String>{'ProductName__c','Brand__c','Spec__c','SerialNo__c','Category0__c','Category1__c','NCCode__c'} );
        searchMap.put('Product__c', proMap.values());
        return searchMap;
    }
    //选择产品
 

    public void setNil(){
        dataJson = '{}';
        saveJson = '[]';
        searchJson = '{}';
    }
    //获取明细
    public List<ProductBean> getDetails(){
        List<ProductBean> tmp = new List<ProductBean>();
        if(ida.Id == null ) return tmp;
        List<InstrumentDeliverynDetails__c> iddList = [select Id ,DeliveryInstrument__c ,LineType__c, Number__c ,DeliveryInstrument__r.Product__r.Brand__c, DeliveryInstrument__r.Product__r.ProductName__c,
            DeliveryInstrument__r.Product__r.Spec__c,DeliveryInstrument__r.ApplicationQuantity__c,DeliveryInstrument__r.DeliveryQuantity__c,DeliveryInstrument__r.BloodSugarOrderDetail1__r.BloodSugarOrder__r.Name,
            DeliveryInstrument__r.SalesPrice__c,DeliveryInstrument__r.QuoteProduct__r.Quote__r.Name ,DeliveryInstrument__r.Measure_Calculate_Product__r.Measure_Calculate__r.Name ,ISE__c,DeliveryInstrument__r.Product__r.Category0__c,
            DeliveryInstrument__r.Product__r.NCCode__c,DeliveryInstrument__r.Product__r.SerialNo__c,DeliveryInstrument__r.Product__r.ManualImportIdentification__c,DeliveryInstrument__r.Product__r.NCinvshortname__c,
            DeliveryInstrument__r.InstrumentPolicy__r.InstrumentPolicy__r.Name,DeliveryInstrument__r.Product__r.InstrumentType__c,DeliveryInstrument__r.Product__r.Name,DeliveryInstrument__r.EndCustomer__r.Name
            from InstrumentDeliverynDetails__c where ReturnToMainTable__c =: ida.Id  ];
        Set<Id> psets = new Set<Id>();

        for(InstrumentDeliverynDetails__c idd :iddList ){
            psets.add(idd.Id);
        }

        //获取配置明细
        Map<Id,List<ConfigBean>> cfgMap =  new Map<Id,List<ConfigBean>>();

        for(NCOutsourcingProducts__c np : [select Id ,InstrumentDeliveryDetails__c,Remarks__c,Number__c,IsStandard__c,OrderMethod__c,ContractProduct__c,
            NCProducts__c,NCProducts__r.ProductName__c, Name,NCProducts__r.NCCode__c,NCProducts__r.Brand__c,NCProducts__r.Spec__c,UnitPrice__c,
            NCProducts__r.Category0__c,NCProducts__r.SerialNo__c,Configuration__c,Configuration__r.Configuration__c,Configuration__r.Name,Configuration__r.Amount__c,
            InstrumentDeliveryDetails__r.DeliveryInstrument__c,

            Configuration__r.OrderMethod__c,Configuration__r.IsStandard__c, NCProducts__r.NCinvshortname__c 

         from NCOutsourcingProducts__c where InstrumentDeliveryDetails__c in :psets order by OrderMethod__c desc ]){

            List<ConfigBean> cfgL = cfgMap.containsKey(np.InstrumentDeliveryDetails__c) ? cfgMap.get(np.InstrumentDeliveryDetails__c) : new List<ConfigBean>();
            cfgL.add(new ConfigBean(np));
            cfgMap.put(np.InstrumentDeliveryDetails__c, cfgL);


        }


        for(InstrumentDeliverynDetails__c idd :iddList ){
            ProductBean p = new ProductBean(idd,cfgMap.get(idd.Id));
            cpNumMap.put(p.cpId,p.num);
            tmp.add(p);
        }
        return tmp;
    }

    private void setErr(String message){
        isErr  =true;
        throw new ControllerException(message);
    }



    //配置清单
    public class ConfigBean{

        public String idId ; //查找的明细id 

        public String productId ;
        public String productName ; 
        public String shortName;

        public String name ;
        public String nccode;
        public String cate0;
        public String spec;
        public String brand ;
        public String serialno;
        public String cpId;//合同明细Id 
         public String model ;//型号

        public Decimal num;

        public Decimal originnum;


        public String orderMethod;
        public String isStandard;

        public String originorderMethod;
        public String originisStandard;

        public String remark;
        public String rid;//记录Id
        public Boolean canRemove;
        public String cfgId;

        public Boolean canChangenum ; 

        public Boolean canChangeProduct;

        public Boolean canChangeorderMethod;
        public Boolean canChangeisStandard;
        public String cooptype;//合作方式
        public Decimal price;


        public ConfigBean(ConfigurationListDetail__c cfg ){
            name = cfg.Name;
            productId = cfg.Configuration__c;
            productName = cfg.Configuration__r.ProductName__c;
            shortName = cfg.Configuration__r.NCinvshortname__c;
            nccode = cfg.Configuration__r.NCCode__c;
            cate0 = cfg.Configuration__r.Category0__c;
            spec = cfg.Configuration__r.Spec__c;
            brand = cfg.Configuration__r.Brand__c;
            serialno = cfg.Configuration__r.SerialNo__c;
            canChangeProduct  = cfg.OrderMethod__c != '仪器配送' ;//productId == null;

            canChangenum =  cfg.OrderMethod__c != '仪器配送' ;
            canChangeorderMethod = cfg.OrderMethod__c != '仪器配送';
            canChangeisStandard = cfg.OrderMethod__c != '仪器配送' ;//false ; 

            num = cfg.Amount__c;
            originnum = cfg.Amount__c;
            orderMethod  =  cfg.OrderMethod__c == null ? null : cfg.OrderMethod__c == '需从我司单独订购' ? '' : cfg.OrderMethod__c; 
            isStandard = cfg.IsStandard__c;
            remark = cfg.Remark__c;
            canRemove = false ;
            cfgId = cfg.Id;

            originorderMethod  = cfg.OrderMethod__c ; 
            originisStandard = cfg.IsStandard__c;


        }

        public ConfigBean(NCOutsourcingProducts__c cfg ){

            //name = cfg.Configuration__r.Name ;
            name = cfg.Name ;
            productId = cfg.NCProducts__c ;
            shortName = cfg.NCProducts__r.NCinvshortname__c;
            productName = cfg.NCProducts__r.ProductName__c;
            nccode = cfg.NCProducts__r.NCCode__c;
            cate0 = cfg.NCProducts__r.Category0__c;
            spec = cfg.NCProducts__r.Spec__c;
            brand = cfg.NCProducts__r.Brand__c;
            serialno = cfg.NCProducts__r.SerialNo__c;

            cpId = cfg.ContractProduct__c;

            canChangeProduct  =  cfg.InstrumentDeliveryDetails__r.DeliveryInstrument__c == null  &&   cfg.Configuration__r.OrderMethod__c != '仪器配送';// cfg.Configuration__r.Configuration__c  == null;

            canChangenum = cfg.Configuration__r.OrderMethod__c != '仪器配送';//cfg.Configuration__r.Amount__c == null && cpId == null ;
            canChangeorderMethod = cfg.Configuration__r.OrderMethod__c != '仪器配送';
            canChangeisStandard =  cfg.Configuration__r.OrderMethod__c != '仪器配送';//cfg.Configuration__r.OrderMethod__c !=  null ;//cfg.Configuration__r.IsStandard__c == null 

            originnum = cfg.Number__c== null ? cfg.Configuration__r.Amount__c :  cfg.Number__c ;
            num = cfg.Number__c;

            orderMethod  = cfg.OrderMethod__c ; 

            isStandard = cfg.IsStandard__c;

           // cooptype = cfg.CoopType__c;
            remark = cfg.Remarks__c;
            rid = cfg.Id;
            canRemove = cfg.Configuration__c == null ;
            cfgId = cfg.Configuration__c;
            price = cfg.UnitPrice__c;

            originorderMethod  = cfg.OrderMethod__c ; 

            originisStandard = cfg.IsStandard__c;



        }
         
        //合同产品
        public ConfigBean(ContractProduct__c cfg  ){
            cpId = cfg.Id;
            name = cfg.Product__r.ProductName__c;
            productId = cfg.Product__c ;
            shortName = cfg.Product__r.NCinvshortname__c;
            productName = cfg.Product__r.ProductName__c;
            nccode = cfg.Product__r.NCCode__c;
            cate0 = cfg.Product__r.Category0__c;
            spec = cfg.Product__r.Spec__c;
            brand = cfg.Product__r.Brand__c;
            serialno = cfg.Product__r.SerialNo__c;
            canChangeProduct  = false;

            canChangeorderMethod = false;
            canChangeisStandard = false;

            originnum = 1;
            num = 1 ;
            canChangenum = false;


            //num = ;
            orderMethod  = '仪器配送' ; 
            //ConfigurationListDetail__c c;
            //c.IsStandard__c = '必须配备（标配）'
            isStandard = '必须配备（标配）';
        
            originorderMethod  = '仪器配送' ; 

            originisStandard = '必须配备（标配）';
            //cooptype = cfg.CoopType__c;
            //remark = cfg.Remarks__c;
            //rid = cfg.Id;
            canRemove = false;



        }
        

        //配套软件 和 设备
        public ConfigBean(Product__c cfg ){
            name = cfg.ProductName__c;
            productId = cfg.Id  ;
            productName = cfg.ProductName__c;
            shortName = cfg.NCinvshortname__c;
            nccode = cfg.NCCode__c;
            cate0 = cfg.Category0__c;
            spec = cfg.Spec__c;
            brand = cfg.Brand__c;
            serialno = cfg.SerialNo__c;
            canRemove = true;
            canChangeProduct = true;
            model = cfg.Model__c;
            canChangenum = false;

            canChangeorderMethod = false;
            canChangeisStandard = false;

            originnum = 1;
            num = 1;
            

        }

    }

    public class LogisticProductBean{

        public String idId ;
        public String productName ;//品名
        public String logicinfo ;
        public String arrivaldate ;
        public String delieverdate;
        public String num;
        public String eno ;
        public String outno ; 

        public LogisticProductBean(InstrumentDeliverynDetails__c idd ){

            idid = idd.Id;
            productName  = idd.DeliveryInstrument__r.Product__r.Name;
            logicinfo = idd.TrackingNumber__c;
            arrivaldate = idd.ActualArrivalTme__c == null ? '' : Utils.date2string(idd.ActualArrivalTme__c,'yyyy-MM-dd');
            delieverdate = idd.ActualDepotTime__c == null ? '' : Utils.date2string(idd.ActualDepotTime__c,'yyyy-MM-dd');
            num = String.valueOf(idd.Number__c);
            eno = idd.FuselageNumber__c;
            outno = idd.OutdoorNo__c ; 
        }
    }
    public class ProductBean{

        public String cpId ; //合同产品Id 
        public String brand ;//品牌
        public String productName ;//品名
        public String spec ;//规格/型号
        public Decimal num ; //数量
        public Decimal total ; //总数 
        public Decimal cannum ;// 可申请数量
        public String nccode ;//存货编码
        public String serialno ; //货号
        public String cate0 ;//类型

        public String idId  ; //明细Id
        public String isISE;//

        public Boolean iscollection ;//是否为组合仪器

        public List<ConfigBean> subs ;//配置清单
        public Decimal price ; //价格
        public String productId;

        public String relatedName ;//相关 测算 报价 政策 

        public Boolean isSmall;//是否是小型仪器
        public String terminal; //终端客户

        public String lineType ; //流水线类型

        //public String cooptype;



        //public String origin ;//来源

        public ProductBean(ContractProduct__c cp ,List<ConfigBean> cfgL ){

            cpId = cp.Id ; 
            brand = cp.Product__r.Brand__c;
            productName = cp.Product__r.Name ;
            spec= cp.Product__r.Spec__c;
            cate0 = cp.Product__r.Category0__c;
            total = cp.ApplicationQuantity__c;
            cannum = cp.DeliveryQuantity__c ;
            nccode = cp.Product__r.NCCode__c;
            serialno = cp.Product__r.SerialNo__c;
            price = cp.SalesPrice__c;
            productId = cp.Product__c;
            num = 1;
            if(cp.QuoteProduct__r.Quote__r.Name !=null )relatedName = cp.QuoteProduct__r.Quote__r.Name ;
            if(cp.Measure_Calculate_Product__r.Measure_Calculate__r.Name  !=null )relatedName = cp.Measure_Calculate_Product__r.Measure_Calculate__r.Name  ;
            if(cp.InstrumentPolicy__r.InstrumentPolicy__r.Name  !=null )relatedName = cp.InstrumentPolicy__r.InstrumentPolicy__r.Name  ;
            if(cp.BloodSugarOrderDetail1__r.BloodSugarOrder__r.Name  !=null )relatedName = cp.BloodSugarOrderDetail1__r.BloodSugarOrder__r.Name  ;
            subs = cfgL;
            isSmall = cp.Product__r.InstrumentType__c != null && cp.Product__r.InstrumentType__c == '非维保仪器';

            terminal = cp.EndCustomer__r.Name;
        }

        public ProductBean(InstrumentDeliverynDetails__c id ,List<ConfigBean> cfgL ){

            idId = id.Id;

            lineType = id.LineType__c ; 

            productId = id.DeliveryInstrument__r.Product__c;
            cpId = id.DeliveryInstrument__c; 
            brand = id.DeliveryInstrument__r.Product__r.Brand__c;
            productName = id.DeliveryInstrument__r.Product__r.Name ;
            spec= id.DeliveryInstrument__r.Product__r.Spec__c;
            cate0 = id.DeliveryInstrument__r.Product__r.Category0__c;
            total = id.DeliveryInstrument__r.ApplicationQuantity__c;
            cannum = id.DeliveryInstrument__r.DeliveryQuantity__c + (id.Number__c == null ? 0 : id.Number__c );
            num = id.Number__c;
            nccode = id.DeliveryInstrument__r.Product__r.NCCode__c;
            serialno = id.DeliveryInstrument__r.Product__r.SerialNo__c;
            price = id.DeliveryInstrument__r.SalesPrice__c;
            isSmall = id.DeliveryInstrument__r.Product__r.InstrumentType__c != null && id.DeliveryInstrument__r.Product__r.InstrumentType__c == '非维保仪器';
            isISE = id.ISE__c;
            subs = cfgL;

            if(id.DeliveryInstrument__r.QuoteProduct__r.Quote__r.Name !=null )relatedName = id.DeliveryInstrument__r.QuoteProduct__r.Quote__r.Name ;
            if(id.DeliveryInstrument__r.Measure_Calculate_Product__r.Measure_Calculate__r.Name  !=null )relatedName = id.DeliveryInstrument__r.Measure_Calculate_Product__r.Measure_Calculate__r.Name  ;
            if(id.DeliveryInstrument__r.InstrumentPolicy__r.InstrumentPolicy__r.Name  !=null )relatedName = id.DeliveryInstrument__r.InstrumentPolicy__r.InstrumentPolicy__r.Name  ;
            if(id.DeliveryInstrument__r.BloodSugarOrderDetail1__r.BloodSugarOrder__r.Name   !=null )relatedName = id.DeliveryInstrument__r.BloodSugarOrderDetail1__r.BloodSugarOrder__r.Name  ;
            terminal = id.DeliveryInstrument__r.EndCustomer__r.Name;
            //iscollection = id.DeliveryInstrument__r.Product__r.ManualImportIdentification__c ;

        }


    }


}